from flask import Flask, request, jsonify
from flask_restx import Api, Resource, fields, Namespace
from typing import List, Dict, Any
from src.infrastructure.sqlite_repository import SQLiteEmailQARepository
from src.application.service import EmailQAService, TaskIdParser
from src.application.task1 import get_email_qa_data
from src.infrastructure.mysql_connection import MySQLConnection
from src.infrastructure.mysql_email_pending_task_repository import MySQLEmailPendingTaskRepository
from src.application.email_pending_task_service import EmailPendingTaskService

app = Flask(__name__)
app.config['SWAGGER_UI_DOC_EXPANSION'] = 'list'
app.config['SWAGGER_UI_OPERATION_ID'] = True
app.config['SWAGGER_UI_REQUEST_DURATION'] = True

# Initialize Flask-RESTX API
api = Api(app, version='1.0.0', title='EmailQA API', 
          description='EmailQA System API Documentation',
          doc='/api/docs/',
          prefix='/api')

DB_PATH = "emailqa1.db"

# MySQL connection setup
mysql_connection = MySQLConnection()

# Initialize database and create tables if they don't exist
def initialize_mysql_database():
    """Initialize MySQL database and create tables if they don't exist"""
    try:
        if mysql_connection.initialize_database():
            print("MySQL database initialized successfully")
        else:
            print("Warning: Failed to initialize MySQL database")
    except Exception as e:
        print(f"Warning: MySQL database initialization failed: {e}")

# Initialize database on startup
initialize_mysql_database()

# Setup repository and service
mysql_repo = MySQLEmailPendingTaskRepository(mysql_connection)
email_pending_task_service = EmailPendingTaskService(mysql_repo)

# Define namespaces
emailqa_ns = Namespace('emailqa', description='EmailQA operations')
email_task_ns = Namespace('email_pending_task', description='Email pending task operations')
health_ns = Namespace('health', description='Health check operations')

api.add_namespace(emailqa_ns)
api.add_namespace(email_task_ns)
api.add_namespace(health_ns)

# Define models for documentation
emailqa_request_model = api.model('EmailQARequest', {
    'content_list': fields.List(fields.String, required=True, 
                               description='List of content strings containing task IDs')
})

emailqa_response_model = api.model('EmailQAResponse', {
    'success': fields.Boolean(required=True, description='Request success status'),
    'data': fields.List(fields.Raw, description='EmailQA data'),
    'task_ids': fields.List(fields.Integer, description='Extracted task IDs'),
    'count': fields.Integer(description='Number of records returned')
})

email_task_request_model = api.model('EmailPendingTaskRequest', {
    'email_id': fields.String(required=True, description='Email identifier'),
    'task_id': fields.String(required=True, description='Unique task identifier'),
    'email_info_json': fields.String(description='Email information in JSON format'),
    'sop_json': fields.String(description='Standard operating procedure in JSON format'),
    'generated_reply': fields.String(description='Generated reply text'),
    'action_type': fields.String(description='Type of action performed'),
    'created_by': fields.String(description='User who created the task')
})

email_task_response_model = api.model('EmailPendingTaskResponse', {
    'success': fields.Boolean(required=True, description='Request success status'),
    'message': fields.String(description='Response message'),
    'task_id': fields.Integer(description='Created task ID'),
    'data': fields.Nested(api.model('EmailPendingTaskData', {
        'email_id': fields.String(description='Email identifier'),
        'task_id': fields.String(description='Task identifier'),
        'email_info_json': fields.String(description='Email information in JSON format'),
        'sop_json': fields.String(description='Standard operating procedure in JSON format'),
        'generated_reply': fields.String(description='Generated reply text'),
        'action_type': fields.String(description='Type of action performed'),
        'created_by': fields.String(description='User who created the task')
    }))
})

health_response_model = api.model('HealthResponse', {
    'status': fields.String(required=True, description='System health status'),
    'message': fields.String(description='Health check message'),
    'database': fields.Nested(api.model('DatabaseInfo', {
        'mysql': fields.Raw(description='MySQL database information')
    }))
})

error_model = api.model('ErrorResponse', {
    'error': fields.String(required=True, description='Error message')
})

# EmailQA endpoints
@emailqa_ns.route('/')
class EmailQAResource(Resource):
    @emailqa_ns.expect(emailqa_request_model)
    @emailqa_ns.response(200, 'Success', emailqa_response_model)
    @emailqa_ns.response(400, 'Bad Request', error_model)
    @emailqa_ns.response(500, 'Internal Server Error', error_model)
    @emailqa_ns.doc('get_emailqa_by_task_ids',
                    description='Get EmailQA data by parsing task IDs from content list')
    def post(self):
        """Get EmailQA data by task IDs"""
        try:
            data = request.get_json()
            if not data or 'content_list' not in data:
                return {'error': 'content_list is required'}, 400
            
            content_list = data['content_list']
            if not isinstance(content_list, list):
                return {'error': 'content_list must be a list'}, 400
            
            task_ids = TaskIdParser.parse_task_ids(content_list)
            
            if not task_ids:
                return {'error': 'No valid task_ids found'}, 400
            
            result = get_email_qa_data(DB_PATH, task_ids)
            
            return {
                'success': True,
                'data': result,
                'task_ids': task_ids,
                'count': len(result)
            }
        
        except ValueError as e:
            return {'error': str(e)}, 400
        except Exception as e:
            return {'error': f'Internal server error: {str(e)}'}, 500

# Email pending task endpoints
@email_task_ns.route('/')
class EmailPendingTaskResource(Resource):
    @email_task_ns.expect(email_task_request_model)
    @email_task_ns.response(201, 'Created', email_task_response_model)
    @email_task_ns.response(400, 'Bad Request', error_model)
    @email_task_ns.response(500, 'Internal Server Error', error_model)
    @email_task_ns.doc('create_email_pending_task',
                    description='Create a new email pending task')
    def post(self):
        """Create a new email pending task"""
        try:
            data = request.get_json()
            if data is None:
                return {'error': 'Request body is required'}, 400
            
            # Validate required fields
            required_fields = ['email_id', 'task_id']
            for field in required_fields:
                if field not in data:
                    return {'error': f'{field} is required'}, 400
            
            # Extract fields
            email_id = data['email_id']
            task_id = data['task_id']
            email_info_json = data.get('email_info_json')
            sop_json = data.get('sop_json')
            generated_reply = data.get('generated_reply')
            action_type = data.get('action_type')
            created_by = data.get('created_by')
            
            # Create the email pending task
            task_id_result = email_pending_task_service.create_email_pending_task(
                email_id=email_id,
                task_id=task_id,
                email_info_json=email_info_json,
                sop_json=sop_json,
                generated_reply=generated_reply,
                action_type=action_type,
                created_by=created_by
            )
            
            return {
                'success': True,
                'message': 'Email pending task created successfully',
                'task_id': task_id_result,
                'data': {
                    'email_id': email_id,
                    'task_id': task_id,
                    'email_info_json': email_info_json,
                    'sop_json': sop_json,
                    'generated_reply': generated_reply,
                    'action_type': action_type,
                    'created_by': created_by
                }
            }, 201
        
        except ValueError as e:
            return {'error': str(e)}, 400
        except Exception as e:
            return {'error': f'Internal server error: {str(e)}'}, 500

# Health check endpoint
@health_ns.route('/')
class HealthResource(Resource):
    @health_ns.response(200, 'Success', health_response_model)
    @health_ns.response(500, 'Internal Server Error', error_model)
    @health_ns.doc('health_check',
                    description='Health check endpoint with database status')
    def get(self):
        """Health check endpoint with database status"""
        try:
            # Get MySQL database information
            db_info = mysql_connection.get_database_info()
            
            return {
                'status': 'healthy' if db_info['connected'] else 'degraded',
                'message': 'EmailQA API is running',
                'database': {
                    'mysql': db_info
                }
            }
        except Exception as e:
            return {
                'status': 'degraded',
                'message': 'EmailQA API is running but database check failed',
                'error': str(e)
            }, 500

if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0', port=6000)